home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / win / vb / inpgrid.exe / TEXT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-10  |  46.2 KB  |  1,337 lines

  1. //---------------------------------------------------------------------------
  2. // Text.c
  3. //---------------------------------------------------------------------------
  4. // Griglia Control
  5. //---------------------------------------------------------------------------
  6.  
  7. #define NOCOMM
  8.  
  9. #include <windows.h>
  10.  
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <ctype.h>
  14. #include <dos.h>
  15. #include "vbapi.h"
  16. #include "griglia.h"
  17.  
  18. #define  GRIGIO_CHIARO RGB (0xc0, 0xc0, 0xc0)
  19. #define  CR                "\r"
  20. #define  LF                "\n"
  21. #define  TB                "\t"
  22.  
  23. static BOOL NEAR     PaintTextLine   (PGRIGLIA, HDC, RECT, RECT,
  24.                                       DWORD, WORD);                                      
  25. static BOOL NEAR     PaintTextCell   (HDC, RECT, LPEXT_INPUT, LPSTR, DWORD);
  26. static LPSTR NEAR    AppendText      (PGRIGLIA, LPSTR);
  27. static LPSTR NEAR    AppendText_Ext  (PGRIGLIA, LPEXT_INPUT, LPSTR);
  28.  
  29. //---------------------------------------------------------------------------
  30. // PaintText
  31. //---------------------------------------------------------------------------
  32. BOOL PaintText (PGRIGLIA lpGrigliaStruct,
  33.                 HDC      hDC,                
  34.                 RECT     rInvalid) {                
  35.  
  36.     RECT  rText;        
  37.     WORD  n;
  38.  
  39.     rText.left  = 0;
  40.     rText.right = 0;
  41.  
  42.     // Paint Fixed Row Text
  43.     if (lpGrigliaStruct->wFixedRows) 
  44.         for (n = 0;    
  45.              n < lpGrigliaStruct->wFixedRows;
  46.              ++n) {
  47.  
  48.         if (CellTBRect (lpGrigliaStruct, n, (LPRECT)&rText)) {    
  49.  
  50.             if (rText.top >= (LONG)rInvalid.bottom)            
  51.                 break;                
  52.             else if (            
  53.                      (            
  54.                       (rText.top    <= (LONG)rInvalid.top)                &&             
  55.                       (rText.bottom >= (LONG)rInvalid.top)         
  56.                      )                                                               ||            
  57.                      (            
  58.                       (rText.top >= (LONG)rInvalid.top)           &&             
  59.                       (rText.top <= (LONG)rInvalid.bottom)             
  60.                      )            
  61.                     ) {       
  62.                 rText.top    += SMALL_RIM;
  63.                 if (rText.bottom < rInvalid.bottom)
  64.                     rText.bottom -= SMALL_RIM;
  65.                 PaintTextLine (lpGrigliaStruct, hDC,                
  66.                                rInvalid, rText,                           
  67.                                GRIGIO_CHIARO, n);                           
  68.             }    
  69.         }        
  70.     }    
  71.  
  72.     // Paint Other Line Text
  73.     for (n = (lpGrigliaStruct->wFixedRows + lpGrigliaStruct->nVScrollPos);
  74.          n < lpGrigliaStruct->wRows;     
  75.         ++n) {     
  76.  
  77.         if (CellTBRect (lpGrigliaStruct, n, (LPRECT)&rText)) {    
  78.  
  79.             if (rText.top >= (LONG)rInvalid.bottom)            
  80.                 break;                
  81.             else if (            
  82.                      (            
  83.                       (rText.top    <= (LONG)rInvalid.top)                &&             
  84.                       (rText.bottom >= (LONG)rInvalid.top)         
  85.                      )                                                               ||            
  86.                      (            
  87.                       (rText.top >= (LONG)rInvalid.top)           &&             
  88.                       (rText.top <= (LONG)rInvalid.bottom)             
  89.                      )            
  90.                     ) {       
  91.                 rText.top    += SMALL_RIM;
  92.                 if (rText.bottom < rInvalid.bottom)
  93.                     rText.bottom -= SMALL_RIM;
  94.                 if ((lpGrigliaStruct->lpHorBars + n)->wStatus == DISABLE_FLAG)
  95.                     PaintTextLine (lpGrigliaStruct, hDC, rInvalid,        
  96.                                    rText, GRIGIO_CHIARO, n);                   
  97.                 else            
  98.                     PaintTextLine (lpGrigliaStruct, hDC, rInvalid,        
  99.                                    rText, (DWORD)NULL, n);                   
  100.             }
  101.         }    
  102.     }
  103.     return (TRUE);
  104. }
  105.  
  106. //---------------------------------------------------------------------------
  107. // PaintTextLine
  108. //---------------------------------------------------------------------------
  109. static BOOL NEAR PaintTextLine (PGRIGLIA lpGrigliaStruct,
  110.                                 HDC      hDC,         
  111.                                 RECT     rInvalid,
  112.                                 RECT     rText,
  113.                                 DWORD    dwBkColor,
  114.                                 WORD     wRow) {
  115.                                     
  116.     WORD      n;
  117.     LPSTR     lpText;
  118.     static    EXT_INPUT eInput;
  119.  
  120.     // Paint Fixed Col Text
  121.     if (lpGrigliaStruct->wFixedCols) 
  122.         for (n = 0;
  123.              n < lpGrigliaStruct->wFixedCols;                                                                  
  124.              ++n) {                                                                  
  125.  
  126.         if (CellLRRect (lpGrigliaStruct, n, (LPRECT)&rText)) {    
  127.  
  128.             if (rText.left >= (LONG)rInvalid.right)
  129.                 break;    
  130.             else if (
  131.                      (
  132.                       (rText.left  <= (LONG)rInvalid.left) &&
  133.                       (rText.right >= (LONG)rInvalid.left)
  134.                      )                                                                ||
  135.                     (
  136.                      (rText.left >= (LONG)rInvalid.left)  &&
  137.                      (rText.left <= (LONG)rInvalid.right)
  138.                     )
  139.                 ) {   
  140.                 rText.left  += SMALL_RIM;
  141.                 if (rText.right < rInvalid.right)
  142.                     rText.right -= SMALL_RIM;
  143.  
  144.                 _fmemset ((LPSTR)&eInput, 0, sizeof (EXT_INPUT));
  145.                 if (lpText = GetCellText_Ext (lpGrigliaStruct, wRow, n, &eInput))
  146.                     PaintTextCell (hDC, rText, &eInput,
  147.                                    lpText, GRIGIO_CHIARO);                   
  148.                 else
  149.                     PaintTextCell (hDC, rText, &eInput,
  150.                                    "", GRIGIO_CHIARO);                   
  151.             }    
  152.         }        
  153.     }
  154.  
  155.     // Paint Other Column Text
  156.     for (n = (lpGrigliaStruct->wFixedCols + lpGrigliaStruct->nHScrollPos);
  157.          n < lpGrigliaStruct->wCols; 
  158.          ++n) {
  159.  
  160.         if (CellLRRect (lpGrigliaStruct, n, (LPRECT)&rText)) {    
  161.  
  162.             if (rText.left >= (LONG)rInvalid.right)
  163.                 break;    
  164.             else if (
  165.                      (
  166.                       (rText.left  <= (LONG)rInvalid.left) &&
  167.                       (rText.right >= (LONG)rInvalid.left)
  168.                      )                                                                ||
  169.                     (
  170.                      (rText.left >= (LONG)rInvalid.left)  &&
  171.                      (rText.left <= (LONG)rInvalid.right)
  172.                     )
  173.                 ) {
  174.  
  175.                 rText.left  += SMALL_RIM;
  176.                 if (rText.right < rInvalid.right)
  177.                     rText.right -= SMALL_RIM;
  178.  
  179.                 _fmemset ((LPSTR)&eInput, 0, sizeof (EXT_INPUT));
  180.                 if (lpText = GetCellText_Ext (lpGrigliaStruct, wRow, n, &eInput)) {
  181.                     if ((lpGrigliaStruct->lpVertBars + n)->wStatus == DISABLE_FLAG)
  182.                         PaintTextCell (hDC, rText, &eInput,
  183.                                        lpText, GRIGIO_CHIARO);                        
  184.                     else {
  185.                         if (dwBkColor)         
  186.                             PaintTextCell (hDC, rText, &eInput,
  187.                                            lpText, dwBkColor);                        
  188.                         else         
  189.                             PaintTextCell (hDC, rText, &eInput,
  190.                                            lpText, GetBkColor (hDC));                        
  191.                     }
  192.                 } else {
  193.                     if ((lpGrigliaStruct->lpVertBars + n)->wStatus == DISABLE_FLAG)
  194.                         PaintTextCell (hDC, rText, &eInput,
  195.                                        "", GRIGIO_CHIARO);                        
  196.                     else {
  197.                         if (dwBkColor)         
  198.                             PaintTextCell (hDC, rText, &eInput,
  199.                                            "", dwBkColor);                        
  200.                         else         
  201.                             PaintTextCell (hDC, rText, &eInput,
  202.                                            "", GetBkColor (hDC));                        
  203.                     }
  204.                 }    
  205.             }    
  206.         }        
  207.     }
  208.  
  209.     return (TRUE);    
  210. }
  211.  
  212. //---------------------------------------------------------------------------
  213. // PaintTextCell
  214. //---------------------------------------------------------------------------
  215. static BOOL NEAR PaintTextCell (HDC         hDC,
  216.                                 RECT        rRect,
  217.                                 LPEXT_INPUT lpExt,
  218.                                 LPSTR       lpStr,
  219.                                 DWORD       dwBkColor) {
  220.  
  221.     BOOL  bRet;
  222.     DWORD dwOldBkColor;
  223.     UINT  nLen;
  224.  
  225.     dwOldBkColor = SetBkColor (hDC, dwBkColor);
  226.     if (
  227.         (lpStr)           &&
  228.         (nLen = _fstrlen (lpStr))
  229.        ) {
  230.  
  231.         if (*(LPSTR)lpExt == (BYTE) PASSWORD)
  232.             bRet = PaintTextCell_Ext (hDC,
  233.                                       rRect,
  234.                                       lpExt,
  235.                                       lpStr);
  236.         else if (_fstrncmp (lpStr, "+_!`", 4) == 0) {
  237.             HRGN hRgn;                
  238.     
  239.             rRect.top    += SMALL_RIM;
  240.             rRect.bottom -= SMALL_RIM;
  241.             rRect.left   += SMALL_RIM;
  242.             rRect.right  -= SMALL_RIM;
  243.  
  244.             if (hRgn = CreateRectRgn (rRect.left, rRect.top,
  245.                                       rRect.right, rRect.bottom)) {
  246.                 FillRgn (hDC, hRgn, GetStockObject (DKGRAY_BRUSH));
  247.                 DeleteObject (hRgn);
  248.             }
  249.            
  250.         } else
  251.             bRet = ExtTextOut ( hDC,
  252.                                 rRect.left, rRect.top,
  253.                                 ETO_CLIPPED | ETO_OPAQUE,
  254.                                 (LPRECT)&rRect,
  255.                                 lpStr, nLen,
  256.                                 (LPINT)NULL);
  257.     } else {
  258.  
  259.         if (*(LPSTR)lpExt == (BYTE) PASSWORD)
  260.             bRet = PaintTextCell_Ext (hDC,
  261.                                       rRect,
  262.                                       lpExt,
  263.                                       " ");
  264.         else
  265.             bRet = ExtTextOut (hDC,
  266.                                 rRect.left, rRect.top,
  267.                                 ETO_CLIPPED | ETO_OPAQUE,
  268.                                 (LPRECT)&rRect,
  269.                                 " ", 1,
  270.                                 (LPINT)NULL);
  271.     }
  272.  
  273.     SetBkColor (hDC, dwOldBkColor);
  274.     return (bRet);
  275.  
  276. }
  277.  
  278. //---------------------------------------------------------------------------
  279. // SetCellText
  280. //---------------------------------------------------------------------------
  281. BOOL SetCellText (PGRIGLIA lpGrigliaStruct,
  282.                   WORD     wRow,
  283.                   WORD     wCol,
  284.                   LPSTR    lpStr) {
  285.  
  286.     RECT rText;
  287.     HDC  hDC;
  288.     BOOL bRet;
  289.     static EXT_INPUT eInput;
  290.  
  291.     _fmemset ((LPSTR)&eInput, 0, sizeof (EXT_INPUT));
  292.     GetCellText_Ext (lpGrigliaStruct, wRow, wCol, &eInput);
  293.  
  294.     if (
  295.         (
  296.          (wRow >= lpGrigliaStruct->wFixedRows) &&
  297.          (wRow < lpGrigliaStruct->wTopRow)
  298.         ) ||
  299.         (
  300.          (wCol >= lpGrigliaStruct->wFixedCols) &&
  301.          (wCol < lpGrigliaStruct->wLeftCol)
  302.         )
  303.        )
  304.        return (TRUE);
  305.  
  306.     if (CellRect (lpGrigliaStruct, wCol, wRow, (LPRECT)&rText)) {        
  307.  
  308.         rText.top    += SMALL_RIM;
  309.         rText.bottom -= SMALL_RIM;
  310.         rText.left   += SMALL_RIM;
  311.         rText.right  -= SMALL_RIM;
  312.  
  313.         // Get DC of Static Window
  314.         if (
  315.             (lpGrigliaStruct->hWndStatic) &&
  316.             (hDC = GetDC (lpGrigliaStruct->hWndStatic))
  317.            ) {
  318.  
  319.             HFONT  hOldFont;
  320.  
  321.             hOldFont = SelectObject (hDC, lpGrigliaStruct->hFont);
  322.  
  323.             // Store Value
  324.             if (
  325.                 (wRow < lpGrigliaStruct->wFixedRows) ||
  326.                 (wCol < lpGrigliaStruct->wFixedCols) ||
  327.                 ((lpGrigliaStruct->lpHorBars + wRow)->wStatus == DISABLE_FLAG) ||
  328.                 ((lpGrigliaStruct->lpVertBars + wCol)->wStatus == DISABLE_FLAG)
  329.                )
  330.                 bRet = PaintTextCell (hDC, rText, &eInput,
  331.                                       lpStr, GRIGIO_CHIARO);
  332.             else {
  333.                 if (
  334.                     (wRow <= lpGrigliaStruct->wSelEndRow) &&
  335.                     (wRow >= lpGrigliaStruct->wSelStartRow) &&
  336.                     (wCol <= lpGrigliaStruct->wSelEndCol) &&
  337.                     (wCol >= lpGrigliaStruct->wSelStartCol) &&
  338.                     (
  339.                      (wRow != lpGrigliaStruct->wCursorRow) ||
  340.                      (wCol != lpGrigliaStruct->wCursorCol)
  341.                     )
  342.                    )
  343.                     InvertRect (hDC, &rText);
  344.                 else if (
  345.                          (wRow == lpGrigliaStruct->wCursorRow) &&
  346.                          (wCol == lpGrigliaStruct->wCursorCol)
  347.                         )
  348.                     PaintCursorLocal (lpGrigliaStruct, hDC);
  349.  
  350.                 bRet = PaintTextCell (hDC, rText, &eInput,
  351.                                       lpStr, GetBkColor (hDC));
  352.                 if (
  353.                     (wRow <= lpGrigliaStruct->wSelEndRow) &&
  354.                     (wRow >= lpGrigliaStruct->wSelStartRow) &&
  355.                     (wCol <= lpGrigliaStruct->wSelEndCol) &&
  356.                     (wCol >= lpGrigliaStruct->wSelStartCol) &&
  357.                     (
  358.                      (wRow != lpGrigliaStruct->wCursorRow) ||
  359.                      (wCol != lpGrigliaStruct->wCursorCol)
  360.                     )
  361.                    )
  362.                     InvertRect (hDC, &rText);
  363.                 else if (
  364.                          (wRow == lpGrigliaStruct->wCursorRow) &&
  365.                          (wCol == lpGrigliaStruct->wCursorCol)
  366.                         )
  367.                     PaintCursorLocal (lpGrigliaStruct, hDC);
  368.             }
  369.  
  370.             SelectObject (hDC, hOldFont);
  371.             ReleaseDC (lpGrigliaStruct->hWndStatic, hDC);
  372.             return (bRet);
  373.         }
  374.         
  375.     }
  376.     return (FALSE);
  377. }
  378.  
  379. //---------------------------------------------------------------------------
  380. // SetEditText
  381. //---------------------------------------------------------------------------
  382. BOOL SetEditText (PGRIGLIA lpGrigliaStruct,
  383.                   WORD     wRow,
  384.                   WORD     wCol) {
  385.  
  386.     int   nLen;
  387.     LPSTR lpStr;
  388.  
  389.     if (lpGrigliaStruct->wEnableEdit == ERASE_FLAG)
  390.         return (TRUE);
  391.  
  392.     if (lpStr = GetCellText (lpGrigliaStruct, wRow, wCol)) {
  393.  
  394.         if (nLen = GetWindowTextLength (lpGrigliaStruct->hWndEdit)) {
  395.             HANDLE hText;
  396.             PSTR   pStr;
  397.  
  398.             if ( hText = LocalAlloc ( LHND,
  399.                                       nLen + 3) ) {
  400.                 pStr = (PSTR) LocalLock (hText);
  401.                 GetWindowText (lpGrigliaStruct->hWndEdit,
  402.                                (LPSTR)pStr, nLen + 1);
  403.  
  404.                 if (lstrcmp (lpStr, (LPSTR)pStr))
  405.                     SetWindowText (lpGrigliaStruct->hWndEdit, lpStr);
  406.  
  407.                 LocalUnlock (hText);
  408.                 LocalFree   (hText);
  409.                 return (TRUE);
  410.             }
  411.         } else {
  412.             if (lstrlen (lpStr))
  413.                 SetWindowText (lpGrigliaStruct->hWndEdit, lpStr);
  414.             else
  415.                 SetWindowText (lpGrigliaStruct->hWndEdit, "");
  416.             return (TRUE);
  417.         }
  418.     } else  {
  419.         SetWindowText (lpGrigliaStruct->hWndEdit, "");
  420.         return (TRUE);
  421.     }
  422. }
  423.  
  424. //---------------------------------------------------------------------------
  425. // GetCellText
  426. //---------------------------------------------------------------------------
  427. LPSTR GetCellText (PGRIGLIA lpGrigliaStruct,
  428.                    WORD     wRow,
  429.                    WORD     wCol) {
  430.  
  431.     WORD wClusRows,
  432.          wClusNum,
  433.          wClusPos;
  434.  
  435.     // Determine Row Cluster and Cluster Position
  436.     wClusRows = (ROW_CLUSTER_SIZE / (sizeof (LPSTR) *
  437.                 lpGrigliaStruct->wCols));
  438.     wClusNum  = wRow / wClusRows;
  439.     wClusPos  = wCol +
  440.                 (wRow -    wClusNum * wClusRows) * lpGrigliaStruct->wCols;
  441.  
  442.     if (
  443.         (wClusNum < ROW_CLUSTER)                             &&
  444.         (lpGrigliaStruct->cRowCluster [wClusNum].hCluster)
  445.        ) {
  446.         LPSTR lpStr;
  447.  
  448.         lpStr = (LPSTR)*((LPLONG)lpGrigliaStruct->cRowCluster [wClusNum].lpCluster +
  449.                                                      wClusPos);
  450.         return (lpStr);
  451.  
  452.     }
  453.     return ((LPSTR)NULL);
  454. }
  455.  
  456. //---------------------------------------------------------------------------
  457. // GetCellText_Ext
  458. //---------------------------------------------------------------------------
  459. LPSTR GetCellText_Ext (PGRIGLIA     lpGrigliaStruct,
  460.                        WORD         wRow,
  461.                        WORD         wCol,
  462.                        LPEXT_INPUT  lpExt) {
  463.  
  464.     WORD wClusRows,
  465.          wClusNum,
  466.          wClusPos;
  467.  
  468.     // Determine Row Cluster and Cluster Position
  469.     wClusRows = (ROW_CLUSTER_SIZE / (sizeof (LPSTR) *
  470.                 lpGrigliaStruct->wCols));
  471.     wClusNum  = wRow / wClusRows;
  472.     wClusPos  = wCol +
  473.                 (wRow -    wClusNum * wClusRows) * lpGrigliaStruct->wCols;
  474.  
  475.     if (
  476.         (wClusNum < ROW_CLUSTER)                             &&
  477.         (lpGrigliaStruct->cRowCluster [wClusNum].hCluster)
  478.        ) {
  479.         LPSTR lpStr;
  480.  
  481.         lpStr = (LPSTR)*((LPLONG)lpGrigliaStruct->cRowCluster [wClusNum].lpCluster +
  482.                                                      wClusPos);
  483.  
  484.                 // return extension
  485.                 if (lpExt)
  486.                     _fmemset (lpExt, 0, sizeof (EXT_INPUT));
  487.                 if (
  488.                     (lpStr) &&
  489.                     (*(lpStr + _fstrlen (lpStr) + 1) == PASSWORD)
  490.                    )
  491.                     _fmemcpy (lpExt,
  492.                               lpStr + _fstrlen (lpStr) + 1,
  493.                               sizeof (EXT_INPUT));
  494.         return (lpStr);
  495.  
  496.     }
  497.     return ((LPSTR)NULL);
  498. }
  499.  
  500. //---------------------------------------------------------------------------
  501. // PutCellText
  502. //---------------------------------------------------------------------------
  503. BOOL PutCellText (PGRIGLIA lpGrigliaStruct,
  504.                   WORD     wRow,                  
  505.                   WORD     wCol,
  506.                   LPSTR    lpText) {
  507.  
  508.     WORD  wClusRows,
  509.           wClusNum,      
  510.           wClusPos;
  511.  
  512.     // Determine Row Cluster and Cluster Position
  513.     wClusRows = (ROW_CLUSTER_SIZE / (sizeof (LPSTR) *
  514.                 lpGrigliaStruct->wCols));
  515.     wClusNum  = wRow / wClusRows;
  516.     wClusPos  = wCol +
  517.                 (wRow - wClusNum * wClusRows) * lpGrigliaStruct->wCols;
  518.  
  519.     // If Necesary Allocate Row Cluster
  520.     if (
  521.         (wClusNum < ROW_CLUSTER)                                &&                        
  522.         (!lpGrigliaStruct->cRowCluster [wClusNum].hCluster)
  523.        ) {
  524.         if (lpGrigliaStruct->cRowCluster [wClusNum].hCluster = GlobalAlloc (GHND,    
  525.                                                                             ROW_CLUSTER_SIZE))                                   
  526.         lpGrigliaStruct->cRowCluster [wClusNum].lpCluster =            
  527.             (LPSTR)GlobalLock (lpGrigliaStruct->cRowCluster                                
  528.                                 [wClusNum].hCluster);                                               
  529.     }    
  530.  
  531.     if (    
  532.         (wClusNum < ROW_CLUSTER)                                                        &&        
  533.         (lpGrigliaStruct->cRowCluster [wClusNum].hCluster)        
  534.        ) {       
  535.  
  536.         LPSTR  lpStoredText;        
  537.  
  538.         lpStoredText = (LPSTR)*((LPLONG)lpGrigliaStruct->cRowCluster [wClusNum].lpCluster + wClusPos);        
  539.  
  540.         if (        
  541.             (lpStoredText)                                  &&
  542.             (_fstrlen (lpText) == _fstrlen (lpStoredText))
  543.            )       
  544.             _fstrcpy (lpStoredText, lpText);
  545.         else {
  546.             // see if there is an extension
  547.             if (
  548.                 (lpStoredText) &&
  549.                 (*(lpStoredText + _fstrlen (lpStoredText) + 1) == PASSWORD)
  550.                ) {
  551.  
  552.                 static EXT_INPUT eInput;
  553.  
  554.                 _fmemset ((LPSTR)&eInput, 0, sizeof (EXT_INPUT));
  555.                 GetCellText_Ext (lpGrigliaStruct, wRow, wCol, &eInput);
  556.                 if (lpStoredText = AppendText_Ext (lpGrigliaStruct,
  557.                                                    (LPEXT_INPUT)&eInput, lpText)) {
  558.                     LPSTR lpStr;
  559.  
  560.                     lpStr               = (LPSTR)((LPLONG)lpGrigliaStruct->cRowCluster [wClusNum].lpCluster +
  561.                                                           wClusPos);
  562.                     *(LPINT)lpStr       = FP_OFF (lpStoredText);
  563.                     *(LPINT)(lpStr + 2) = FP_SEG (lpStoredText);
  564.                 }
  565.  
  566.             } else if (lpStoredText = AppendText (lpGrigliaStruct, lpText)) {
  567.                 LPSTR lpStr;                
  568.  
  569.                 lpStr               = (LPSTR)((LPLONG)lpGrigliaStruct->cRowCluster [wClusNum].lpCluster +                
  570.                                                         wClusPos);       
  571.                 *(LPINT)lpStr       = FP_OFF (lpStoredText);                
  572.                 *(LPINT)(lpStr + 2) = FP_SEG (lpStoredText);                
  573.             }            
  574.         }        
  575.         return (TRUE);        
  576.     }    
  577.     return (FALSE);    
  578. }
  579.  
  580. //---------------------------------------------------------------------------
  581. // PutCellText_Ext
  582. //---------------------------------------------------------------------------
  583. BOOL PutCellText_Ext (PGRIGLIA    lpGrigliaStruct,
  584.                       WORD        wRow,
  585.                       WORD        wCol,
  586.                       LPEXT_INPUT lpExt,
  587.                       LPSTR       lpText) {
  588.  
  589.     WORD  wClusRows,
  590.           wClusNum,      
  591.           wClusPos;
  592.  
  593.     // Determine Row Cluster and Cluster Position
  594.     wClusRows = (ROW_CLUSTER_SIZE / (sizeof (LPSTR) *
  595.                 lpGrigliaStruct->wCols));
  596.     wClusNum  = wRow / wClusRows;
  597.     wClusPos  = wCol +
  598.                 (wRow - wClusNum * wClusRows) * lpGrigliaStruct->wCols;
  599.  
  600.     // If Necesary Allocate Row Cluster
  601.     if (
  602.         (wClusNum < ROW_CLUSTER)                                &&                        
  603.         (!lpGrigliaStruct->cRowCluster [wClusNum].hCluster)
  604.        ) {
  605.         if (lpGrigliaStruct->cRowCluster [wClusNum].hCluster = GlobalAlloc (GHND,    
  606.                                                                             ROW_CLUSTER_SIZE))                                   
  607.         lpGrigliaStruct->cRowCluster [wClusNum].lpCluster =            
  608.             (LPSTR)GlobalLock (lpGrigliaStruct->cRowCluster                                
  609.                                 [wClusNum].hCluster);                                               
  610.     }    
  611.  
  612.     if (    
  613.         (wClusNum < ROW_CLUSTER)                                                        &&        
  614.         (lpGrigliaStruct->cRowCluster [wClusNum].hCluster)        
  615.        ) {       
  616.  
  617.         LPSTR  lpStoredText;        
  618.  
  619.         lpStoredText = (LPSTR)*((LPLONG)lpGrigliaStruct->cRowCluster [wClusNum].lpCluster + wClusPos);        
  620.  
  621.         if (        
  622.             (lpStoredText)                                              &&
  623.             (*(lpStoredText + _fstrlen (lpStoredText) + 1) == PASSWORD) &&
  624.             (_fstrlen (lpText) == _fstrlen (lpStoredText))
  625.            ) {
  626.             _fstrcpy (lpStoredText, lpText);
  627.             _fmemcpy (lpStoredText + _fstrlen (lpText) + 1,
  628.                       lpExt, sizeof (EXT_INPUT));
  629.  
  630.         } else {
  631.             if (lpStoredText = AppendText_Ext (lpGrigliaStruct, lpExt, lpText)) {
  632.                 LPSTR lpStr;
  633.  
  634.                 lpStr               = (LPSTR)((LPLONG)lpGrigliaStruct->cRowCluster [wClusNum].lpCluster +
  635.                                                         wClusPos);
  636.                 *(LPINT)lpStr       = FP_OFF (lpStoredText);
  637.                 *(LPINT)(lpStr + 2) = FP_SEG (lpStoredText);
  638.             }
  639.         }
  640.         return (TRUE);        
  641.     }    
  642.     return (FALSE);    
  643. }
  644.  
  645. //---------------------------------------------------------------------------
  646. // AppendText
  647. //---------------------------------------------------------------------------
  648. static LPSTR NEAR AppendText (PGRIGLIA     lpGrigliaStruct,
  649.                               LPSTR     lpText) {                          
  650.  
  651.     SHORT n;
  652.     WORD  wLen, wTemp;
  653.     LONG  lClusSize;
  654.  
  655.     wLen = (WORD)_fstrlen (lpText) + 1;
  656.     for (n = 0; n < TEXT_CLUSTER; ++n) {
  657.  
  658.         // Text Cluster Exists ?
  659.         if (lpGrigliaStruct->cTextCluster [n].hCluster) {
  660.  
  661.             LPSTR lpTemp;
  662.  
  663.             lpTemp = lpGrigliaStruct->cTextCluster [n].lpCluster;
  664.  
  665.             lClusSize = (LONG)(*(LPWORD)lpTemp + 1);
  666.  
  667.             if ((lClusSize + wLen + 10) < (LONG)TEXT_CLUSTER_SIZE) {
  668.  
  669.                 // Update Length
  670.                 wTemp           = wLen + LOWORD(lClusSize);
  671.                 *(LPWORD)lpTemp = wTemp;
  672.  
  673.                 // Append String
  674.                 _fstrncpy (lpTemp + LOWORD(lClusSize) + 3, lpText, wLen - 1);
  675.                 *(lpTemp + LOWORD (lClusSize) + wLen + 2) = 0;
  676.                 *(lpTemp + LOWORD (lClusSize) + wLen + 3) = 0;
  677.                 return (lpGrigliaStruct->cTextCluster [n].lpCluster +
  678.                                 LOWORD(lClusSize) + 3);
  679.             } else {    
  680.                 n = n;        
  681.             }    
  682.         } else if (lpGrigliaStruct->cTextCluster [n].hCluster =
  683.                     GlobalAlloc (GHND, (DWORD)TEXT_CLUSTER_SIZE)) {       
  684.  
  685.                 LPSTR lpTemp;
  686.  
  687.                 lpGrigliaStruct->cTextCluster [n].lpCluster =
  688.                                 (LPSTR)GlobalLock (lpGrigliaStruct->cTextCluster [n].
  689.                                                                    hCluster);
  690.                 lpTemp = lpGrigliaStruct->cTextCluster [n].lpCluster;
  691.  
  692.                 // Initialize First Two Bytes to Length
  693.                 *(LPWORD)lpTemp = wLen;
  694.  
  695.                 // Append String
  696.                 _fstrncpy (lpTemp + 2, lpText, wLen - 1);
  697.                 *(lpTemp + wLen + 1) = 0;
  698.                 *(lpTemp + wLen + 2) = 0;
  699.                 return (lpTemp + 2);
  700.  
  701.         }
  702.     }
  703.     return ((LPSTR)NULL);
  704. }
  705.  
  706. //---------------------------------------------------------------------------
  707. // AppendText_Ext
  708. //---------------------------------------------------------------------------
  709. static LPSTR NEAR AppendText_Ext (PGRIGLIA    lpGrigliaStruct,
  710.                                   LPEXT_INPUT lpExt,
  711.                                   LPSTR       lpText) {
  712.  
  713.     SHORT n;
  714.     WORD  wLen, wTemp;
  715.     LONG  lClusSize;
  716.  
  717.     wLen = (WORD)_fstrlen (lpText) + sizeof (EXT_INPUT);
  718.     for (n = 0; n < TEXT_CLUSTER; ++n) {
  719.  
  720.         // Text Cluster Exists ?
  721.         if (lpGrigliaStruct->cTextCluster [n].hCluster) {
  722.  
  723.             LPSTR lpTemp;
  724.  
  725.             lpTemp = lpGrigliaStruct->cTextCluster [n].lpCluster;
  726.  
  727.             lClusSize = (LONG)(*(LPWORD)lpTemp + 1);
  728.  
  729.             if ((lClusSize + wLen + 10) < (LONG)TEXT_CLUSTER_SIZE) {
  730.  
  731.                 // Update Length
  732.                 wTemp           = wLen + LOWORD(lClusSize);
  733.                 *(LPWORD)lpTemp = wTemp;
  734.  
  735.                 // Append String
  736.                 _fstrncpy (lpTemp + LOWORD(lClusSize) + 3,
  737.                            lpText, _fstrlen (lpText));
  738.                 *(lpTemp + LOWORD (lClusSize) + _fstrlen (lpText) + 3) = 0;
  739.                 _fmemcpy  (lpTemp + LOWORD(lClusSize) + _fstrlen (lpText) + 3 + 1,
  740.                            lpExt, sizeof (EXT_INPUT));
  741.                 return (lpGrigliaStruct->cTextCluster [n].lpCluster +
  742.                         LOWORD(lClusSize) + 3);
  743.             } else {    
  744.                 n = n;        
  745.             }    
  746.         } else if (lpGrigliaStruct->cTextCluster [n].hCluster =
  747.                     GlobalAlloc (GHND, (DWORD)TEXT_CLUSTER_SIZE)) {       
  748.  
  749.                 LPSTR lpTemp;
  750.  
  751.                 lpGrigliaStruct->cTextCluster [n].lpCluster =
  752.                                 (LPSTR)GlobalLock (lpGrigliaStruct->cTextCluster [n].
  753.                                                                    hCluster);
  754.                 lpTemp = lpGrigliaStruct->cTextCluster [n].lpCluster;
  755.  
  756.                 // Initialize First Two Bytes to Length
  757.                 *(LPWORD)lpTemp = wLen;
  758.  
  759.                 // Append String
  760.                 _fstrncpy (lpTemp + 2,
  761.                            lpText, _fstrlen (lpText));
  762.                 *(lpTemp + _fstrlen (lpText) + 2) = 0;
  763.                 _fmemcpy  (lpTemp + 2 + _fstrlen (lpText) + 1,
  764.                            lpExt, sizeof (EXT_INPUT));
  765.                 return (lpTemp + 2);
  766.  
  767.         }
  768.     }
  769.     return ((LPSTR)NULL);
  770. }
  771.  
  772. //---------------------------------------------------------------------------
  773. // WriteClip
  774. //---------------------------------------------------------------------------
  775. BOOL WriteClip (PGRIGLIA lpGrigliaStruct,
  776.                  LONG     lp,
  777.                 HCTL     hctl) {
  778.  
  779.     HANDLE hText;
  780.     LPSTR  lpText, lpStr;
  781.     SHORT  n, m;
  782.     HSZ FAR *lpTemp;
  783.  
  784.     if (hText = GlobalAlloc (GHND, (DWORD)0xffff)) {
  785.         LPSTR lpText;
  786.  
  787.         lpText  = (LPSTR)GlobalLock (hText);
  788.         *lpText = 0;
  789.  
  790.         for (n =  (SHORT)lpGrigliaStruct->wSelStartRow;
  791.               n <= (SHORT)lpGrigliaStruct->wSelEndRow;
  792.               ++n) {
  793.  
  794.             if (n > (SHORT)lpGrigliaStruct->wSelStartRow) {
  795.                 lstrcat (lpText, CR);
  796.                 lstrcat (lpText, LF);
  797.             }
  798.  
  799.             for (m =  (SHORT)lpGrigliaStruct->wSelStartCol;
  800.                  m <= (SHORT)lpGrigliaStruct->wSelEndCol;
  801.                  ++m) {
  802.  
  803.                 if (m > (SHORT)lpGrigliaStruct->wSelStartCol)
  804.                     lstrcat (lpText, TB);
  805.                 if (lpStr = GetCellText (lpGrigliaStruct, n ,m))
  806.                     lstrcat (lpText, lpStr);
  807.             }
  808.         }
  809.         if (lstrlen (lpText)) {
  810.             lpTemp  = (HSZ FAR *)lp;
  811.             *lpTemp = VBCreateHsz ((_segment)hctl, lpText);
  812.         } else {
  813.             lpTemp  = (HSZ FAR *)lp;
  814.             *lpTemp = VBCreateHsz ((_segment)hctl, (LPSTR)"");
  815.         }
  816.  
  817.         GlobalUnlock (hText);
  818.         GlobalFree   (hText);
  819.         return (TRUE);
  820.  
  821.     }
  822.  
  823.     lpTemp  = (HSZ FAR *)lp;
  824.     *lpTemp = VBCreateHsz ((_segment)hctl, lpText);
  825.     return (FALSE);
  826. }
  827.  
  828. //---------------------------------------------------------------------------
  829. // ReadClip
  830. //---------------------------------------------------------------------------
  831. BOOL ReadClip (PGRIGLIA lpGrigliaStruct,
  832.                LONG     lp,
  833.                HCTL         hctl) {
  834.  
  835.     LPSTR  lpText = (LPSTR)lp;
  836.     LPSTR  lpTab, lpCr, lpLf;
  837.     SHORT  n, m, nOffset = 0, nSize, nLen;
  838.  
  839.     nLen = lstrlen (lpText);
  840.     for (n =  (SHORT)lpGrigliaStruct->wSelStartRow;
  841.          n <= (SHORT)lpGrigliaStruct->wSelEndRow;
  842.          ++n) {
  843.  
  844.         for (m =  (SHORT)lpGrigliaStruct->wSelStartCol;
  845.              m <= (SHORT)lpGrigliaStruct->wSelEndCol;
  846.              ++m) {
  847.  
  848.             lpTab = _fstrchr (lpText + nOffset, '\t');
  849.             lpCr  = _fstrchr (lpText + nOffset, '\r');
  850.             lpLf  = _fstrchr (lpText + nOffset, '\n');
  851.  
  852.             if (
  853.                 (!lpTab) && (!lpCr) && (!lpLf)
  854.                ) {
  855.                    if (nLen - nOffset) {
  856.                     if (PutCellText (lpGrigliaStruct, n, m,
  857.                                      lpText + nOffset))
  858.                         SetCellText (lpGrigliaStruct, n, m,
  859.                                      lpText + nOffset);
  860.                     nOffset = nLen;
  861.                    } else {
  862.                     if (PutCellText (lpGrigliaStruct, n, m,
  863.                                      (LPSTR) ""))
  864.                         SetCellText (lpGrigliaStruct, n, m,
  865.                                      (LPSTR) "");
  866.                    }
  867.  
  868.             } else if (!lpTab) {
  869.  
  870.                 // no more tab found
  871.                 if ((lpLf) || (lpCr)) {
  872.                     if (lpLf && lpCr)
  873.                         nSize   = min ((lpLf - lpText - nOffset),
  874.                                        (lpCr - lpText - nOffset));
  875.                     else if (lpLf)
  876.                         nSize   = (lpLf - lpText - nOffset);
  877.                     else
  878.                         nSize   = (lpCr - lpText - nOffset);
  879.  
  880.                     // cut string at appropriate size
  881.                     *(lpText + nOffset + nSize) = 0;
  882.  
  883.                     if (nSize) {
  884.                         if (PutCellText (lpGrigliaStruct, n, m,
  885.                                          lpText + nOffset))
  886.                             SetCellText (lpGrigliaStruct, n, m,
  887.                                          lpText + nOffset);
  888.                        } else {
  889.                         if (PutCellText (lpGrigliaStruct, n, m,
  890.                                          (LPSTR) ""))
  891.                             SetCellText (lpGrigliaStruct, n, m,
  892.                                          (LPSTR) "");
  893.                        }
  894.  
  895.                     if (lpLf && lpCr)
  896.                         nOffset = max ((lpLf - lpText + 1),
  897.                                        (lpCr - lpText + 1));
  898.                     else if (lpLf)
  899.                         nOffset = (lpLf - lpText + 1);
  900.                     else
  901.                         nOffset = (lpCr - lpText + 1);
  902.                     break;
  903.  
  904.                 } else {
  905.                     if (nLen - nOffset) {
  906.                         if (PutCellText (lpGrigliaStruct, n, m,
  907.                                          lpText + nOffset))
  908.                             SetCellText (lpGrigliaStruct, n, m,
  909.                                          lpText + nOffset);
  910.                        } else {
  911.                         if (PutCellText (lpGrigliaStruct, n, m,
  912.                                          (LPSTR) ""))
  913.                             SetCellText (lpGrigliaStruct, n, m,
  914.                                          (LPSTR) "");
  915.                        }
  916.  
  917.                     if (lpGrigliaStruct->hszClip)
  918.                         VBDestroyHsz (lpGrigliaStruct->hszClip);
  919.                     if (lpGrigliaStruct->hszClip =
  920.                         VBCreateHsz ((_segment)hctl,(LPSTR)lp))
  921.                         return (TRUE);
  922.                     return (FALSE);
  923.  
  924.                 }
  925.  
  926.             } else if (
  927.                        (lpLf && ((lpLf - lpText) < (lpTab - lpText))) ||
  928.                        (lpCr && ((lpCr - lpText) < (lpTab - lpText)))
  929.                       ) {
  930.                 // found Lf before Tab
  931.                 if (lpLf && lpCr)
  932.                     nSize   = min ((lpLf - lpText - nOffset),
  933.                                    (lpCr - lpText - nOffset));
  934.                 else if (lpLf)
  935.                     nSize   = (lpLf - lpText - nOffset);
  936.                 else
  937.                     nSize   = (lpCr - lpText - nOffset);
  938.  
  939.                 // cut string at appropriate size
  940.                 *(lpText + nOffset + nSize) = 0;
  941.  
  942.                 if (nSize) {
  943.                     if (PutCellText (lpGrigliaStruct, n, m,
  944.                                      lpText + nOffset))
  945.                         SetCellText (lpGrigliaStruct, n, m,
  946.                                      lpText + nOffset);
  947.                    } else {
  948.                     if (PutCellText (lpGrigliaStruct, n, m,
  949.                                      (LPSTR) ""))
  950.                         SetCellText (lpGrigliaStruct, n, m,
  951.                                      (LPSTR) "");
  952.                    }
  953.  
  954.                 if (lpLf && lpCr)
  955.                     nOffset = max ((lpLf - lpText + 1),
  956.                                    (lpCr - lpText)+ 1);
  957.                 else if (lpLf)
  958.                     nOffset = (lpLf - lpText + 1);
  959.                 else
  960.                     nOffset = (lpCr - lpText + 1);
  961.  
  962.                 break;
  963.  
  964.             } else {
  965.  
  966.                 // cut string at tab
  967.                 *lpTab  = 0;
  968.  
  969.                 // insert text into appropriate cell
  970.                 if (lpTab - lpText - nOffset) {
  971.                     if (PutCellText (lpGrigliaStruct, n, m,
  972.                                      lpText + nOffset))
  973.                         SetCellText (lpGrigliaStruct, n, m,
  974.                                      lpText + nOffset);
  975.                    } else {
  976.                     if (PutCellText (lpGrigliaStruct, n, m,
  977.                                      (LPSTR) ""))
  978.                         SetCellText (lpGrigliaStruct, n, m,
  979.                                      (LPSTR) "");
  980.                    }
  981.  
  982.                 // recompute nOffset
  983.                 nOffset = (lpTab - lpText + 1);
  984.             }
  985.  
  986.         }
  987.         if (m > (SHORT)lpGrigliaStruct->wSelEndCol) {
  988.             lpCr  = _fstrchr (lpText + nOffset, '\r');
  989.             lpLf  = _fstrchr (lpText + nOffset, '\n');
  990.             if (lpLf && lpCr)
  991.                 nOffset = max ((lpLf - lpText),
  992.                                (lpCr - lpText));
  993.             else if (lpLf)
  994.                 nOffset = (lpLf - lpText);
  995.             else if (lpCr)
  996.                 nOffset = (lpCr - lpText);
  997.         }
  998.     }
  999.     if (lpGrigliaStruct->hszClip)
  1000.         VBDestroyHsz (lpGrigliaStruct->hszClip);
  1001.     if (lpGrigliaStruct->hszClip = VBCreateHsz ((_segment)hctl,(LPSTR)lp))
  1002.         return (TRUE);
  1003.     return (FALSE);
  1004. }
  1005.  
  1006. //---------------------------------------------------------------------------
  1007. // InsertLinesText
  1008. //---------------------------------------------------------------------------
  1009. BOOL InsertLinesText (PGRIGLIA     lpGrigliaStruct,
  1010.                       WORD      wRow,                          
  1011.                       WORD      wInsertRows) {      
  1012.  
  1013.     WORD  wClusRows,
  1014.           wClusNum, wClusNumFrom, wClusNumTo,  
  1015.           wClusPos, wClusPosFrom, wClusPosTo,  
  1016.           n;  
  1017.     LPSTR lpPtr,lpPtrFrom, lpPtrTo;
  1018.  
  1019.     // Determine Row Cluster and Cluster Position
  1020.     wClusRows = (ROW_CLUSTER_SIZE / (sizeof (LPSTR) *
  1021.                 lpGrigliaStruct->wCols));            
  1022.  
  1023.     for (n = lpGrigliaStruct->wRows - wInsertRows - 1; n >= wRow; --n) {
  1024.  
  1025.         // positions to copy from    
  1026.         wClusNumFrom = n / wClusRows;    
  1027.         wClusPosFrom = (n -     wClusNumFrom * wClusRows)  *    
  1028.                        lpGrigliaStruct->wCols;                
  1029.         lpPtrFrom    = (LPSTR)((LPLONG)lpGrigliaStruct->cRowCluster [wClusNumFrom].lpCluster + wClusPosFrom);
  1030.  
  1031.         // positions to copy to    
  1032.         wClusNumTo = (n + wInsertRows) / wClusRows;    
  1033.         wClusPosTo = ((n + wInsertRows) - wClusNumTo * wClusRows) *    
  1034.                      lpGrigliaStruct->wCols;             
  1035.         lpPtrTo    = (LPSTR)((LPLONG)lpGrigliaStruct->cRowCluster [wClusNumTo].lpCluster + wClusPosTo);
  1036.  
  1037.         _fmemcpy (lpPtrTo,
  1038.                   lpPtrFrom,        
  1039.                   (sizeof (LPSTR) * lpGrigliaStruct->wCols));  
  1040.  
  1041.     }    
  1042.  
  1043.     for (n = wRow; n < wRow + wInsertRows; ++n) {
  1044.  
  1045.         // positions to copy from    
  1046.         wClusNum = n / wClusRows;    
  1047.         wClusPos = (n - wClusNum * wClusRows) *    
  1048.                    lpGrigliaStruct->wCols;                        
  1049.         lpPtr    = (LPSTR)((LPLONG)lpGrigliaStruct->cRowCluster [wClusNum].lpCluster + wClusPos);
  1050.         _fmemset (lpPtr,
  1051.                       0,
  1052.                       (sizeof (LPSTR) * lpGrigliaStruct->wCols));
  1053.  
  1054.     }
  1055.     return (TRUE);
  1056. }
  1057.  
  1058. //---------------------------------------------------------------------------
  1059. // DeleteLinesText
  1060. //---------------------------------------------------------------------------
  1061. BOOL DeleteLinesText (PGRIGLIA     lpGrigliaStruct,
  1062.                       WORD      wRow,
  1063.                       WORD      wDeleteRows) {
  1064.  
  1065.     WORD  wClusRows,
  1066.           wClusNum, wClusNumFrom, wClusNumTo,      
  1067.           wClusPos, wClusPosFrom, wClusPosTo,
  1068.           n;
  1069.     LPSTR lpPtr,lpPtrFrom, lpPtrTo;
  1070.  
  1071.     // Determine Row Cluster and Cluster Position
  1072.     wClusRows = (ROW_CLUSTER_SIZE / (sizeof (LPSTR) *
  1073.                                      lpGrigliaStruct->wCols));
  1074.  
  1075.     for (n = wRow; n < lpGrigliaStruct->wRows - wDeleteRows; ++n) {
  1076.  
  1077.         // positions to copy from        
  1078.         wClusNumTo = n / wClusRows;    
  1079.         wClusPosTo = (n - wClusNumTo * wClusRows)  *    
  1080.                           lpGrigliaStruct->wCols;            
  1081.         lpPtrTo    = (LPSTR)((LPLONG)lpGrigliaStruct->cRowCluster [wClusNumTo].lpCluster + wClusPosTo);
  1082.  
  1083.         // positions to copy to    
  1084.         wClusNumFrom = (n + wDeleteRows) / wClusRows;    
  1085.         wClusPosFrom = ((n + wDeleteRows) - wClusNumFrom * wClusRows) *    
  1086.                                             lpGrigliaStruct->wCols;   
  1087.         lpPtrFrom    = (LPSTR)((LPLONG)lpGrigliaStruct->cRowCluster [wClusNumFrom].lpCluster + wClusPosFrom);
  1088.  
  1089.         _fmemcpy (lpPtrTo,
  1090.                   lpPtrFrom,    
  1091.                   (sizeof (LPSTR) * lpGrigliaStruct->wCols));  
  1092.  
  1093.     }
  1094.  
  1095.     for (n = lpGrigliaStruct->wRows - wDeleteRows;
  1096.              n < lpGrigliaStruct->wRows; ++n) {
  1097.  
  1098.         // positions to copy from    
  1099.         wClusNum = n / wClusRows;    
  1100.         wClusPos = (n - wClusNum * wClusRows) *    
  1101.                         lpGrigliaStruct->wCols;                    
  1102.         lpPtr    = (LPSTR)((LPLONG)lpGrigliaStruct->cRowCluster [wClusNum].lpCluster + wClusPos);
  1103.         _fmemset (lpPtr,
  1104.                   0,
  1105.                   (sizeof (LPSTR) * lpGrigliaStruct->wCols));
  1106.  
  1107.     }    
  1108.     return (TRUE);
  1109. }
  1110.  
  1111. //---------------------------------------------------------------------------
  1112. // FindText
  1113. //---------------------------------------------------------------------------
  1114. BOOL FindText (PGRIGLIA     lpGrigliaStruct,
  1115.                LPFINDTEXT     lpFind) {
  1116.  
  1117.     WORD    wClusRows,
  1118.         wClusNum,
  1119.         wClusPos,
  1120.         n;
  1121.     LPSTR    lpStr;
  1122.     LPFINDTEXT    lpLoop;
  1123.     BOOL  bFound;
  1124.  
  1125.     if (!lpFind)
  1126.     return (FALSE);
  1127.  
  1128.     wClusRows = (ROW_CLUSTER_SIZE / (sizeof (LPSTR) *
  1129.         lpGrigliaStruct->wCols));
  1130.  
  1131.     for (n = 0; n < lpGrigliaStruct->wRows; ++n) {
  1132.  
  1133.     bFound = TRUE;
  1134.     lpLoop = lpFind;
  1135.  
  1136.     // loop over all search blocks
  1137.     while (
  1138.         (bFound)         &&
  1139.         (lpLoop->wCol != 0xffff) &&
  1140.         (lpLoop->lpText)
  1141.           ) {
  1142.  
  1143.         wClusNum  = n / wClusRows;
  1144.         wClusPos  = lpLoop->wCol +
  1145.             (n - wClusNum * wClusRows) *
  1146.             lpGrigliaStruct->wCols;
  1147.         lpStr = (LPSTR)*((LPLONG)
  1148.             lpGrigliaStruct->cRowCluster [wClusNum].lpCluster +
  1149.             wClusPos);
  1150.  
  1151.         if (
  1152.         (!lpStr)  ||
  1153.         (_fstrcmp (lpStr, lpLoop->lpText))
  1154.            )
  1155.         bFound = FALSE;
  1156.  
  1157.         // fetch next search column
  1158.         ++lpLoop;
  1159.     }
  1160.  
  1161.     if (bFound)
  1162.                 return (n);
  1163.     }
  1164.     return (0xffff);
  1165. }
  1166.  
  1167. //---------------------------------------------------------------------------
  1168. // ClearText
  1169. //---------------------------------------------------------------------------
  1170. void ClearText (PGRIGLIA lpGrigliaStruct) {
  1171.         
  1172.     UINT n;
  1173.     
  1174.     // Release Text Blocks
  1175.     for (n = 0; n < (int) ROW_CLUSTER; ++n) {
  1176.         if (lpGrigliaStruct->cRowCluster [n].hCluster) {    
  1177.             GlobalUnlock (lpGrigliaStruct->cRowCluster [n].hCluster);        
  1178.             GlobalFree   (lpGrigliaStruct->cRowCluster [n].hCluster);        
  1179.             lpGrigliaStruct->cRowCluster [n].hCluster  = (HANDLE)NULL;        
  1180.             lpGrigliaStruct->cRowCluster [n].lpCluster = (LPSTR)NULL;        
  1181.         }    
  1182.     }
  1183.  
  1184.     // Release Text Blocks
  1185.     for (n = 0; n < TEXT_CLUSTER; ++n) {
  1186.         if (lpGrigliaStruct->cTextCluster [n].hCluster) {    
  1187.             GlobalUnlock (lpGrigliaStruct->cTextCluster [n].hCluster);        
  1188.             GlobalFree   (lpGrigliaStruct->cTextCluster [n].hCluster);        
  1189.             lpGrigliaStruct->cTextCluster [n].hCluster  = (HANDLE)NULL;        
  1190.             lpGrigliaStruct->cTextCluster [n].lpCluster = (LPSTR)NULL;        
  1191.         }    
  1192.     }
  1193. }
  1194.  
  1195. //---------------------------------------------------------------------------
  1196. // CompareLines
  1197. //---------------------------------------------------------------------------
  1198. SHORT CompareLines (PGRIGLIA         lpGrigliaStruct,
  1199.                     LPFINDTEXT       lpFind,
  1200.                     UINT             nRow1,
  1201.                     UINT             nRow2) {
  1202.                  
  1203.     UINT  wClusRows, 
  1204.           wClusNum,
  1205.           wClusPos;
  1206.     LPFINDTEXT lpLoop;
  1207.     LPSTR      lpStr1, lpStr2;
  1208.     BOOL  bFound;
  1209.     
  1210.     if ( !lpFind)
  1211.     return (FALSE);
  1212.  
  1213.     wClusRows = (ROW_CLUSTER_SIZE / (sizeof (LPSTR) *
  1214.         lpGrigliaStruct->wCols));
  1215.  
  1216.     bFound = TRUE;
  1217.     lpLoop = lpFind;
  1218.  
  1219.     // loop over all search blocks
  1220.     while (
  1221.             (bFound)                 &&
  1222.             (lpLoop->wCol != 0xffff) 
  1223.           ) {
  1224.  
  1225.         wClusNum  = nRow1 / wClusRows;
  1226.         wClusPos  = lpLoop->wCol +
  1227.                     (nRow1 - wClusNum * wClusRows) *
  1228.                     lpGrigliaStruct->wCols;
  1229.         lpStr1    = (LPSTR)*((LPLONG)
  1230.                     lpGrigliaStruct->cRowCluster [wClusNum].lpCluster +
  1231.                     wClusPos);
  1232.         wClusNum  = nRow2 / wClusRows;
  1233.         wClusPos  = lpLoop->wCol +
  1234.                     (nRow2 - wClusNum * wClusRows) *
  1235.                     lpGrigliaStruct->wCols;
  1236.         lpStr2    = (LPSTR)*((LPLONG)
  1237.                     lpGrigliaStruct->cRowCluster [wClusNum].lpCluster +
  1238.                     wClusPos);
  1239.  
  1240.         if (
  1241.             (!lpStr1)  ||
  1242.             (!lpStr2)  
  1243.            ) 
  1244.             bFound = FALSE;
  1245.         else    
  1246.             bFound = (_fstrcmp (lpStr1, lpStr2) == 0);
  1247.  
  1248.         // fetch next search column
  1249.         ++lpLoop;
  1250.     }       
  1251.     if (    
  1252.         (!lpStr1)  ||    
  1253.         (!lpStr2)      
  1254.        )    
  1255.         return (0);
  1256.     else
  1257.         return (_fstrcmp (lpStr1, lpStr2));
  1258. }
  1259.  
  1260. //---------------------------------------------------------------------------
  1261. // SwitchLines
  1262. //---------------------------------------------------------------------------
  1263. void SwitchLines (PGRIGLIA         lpGrigliaStruct,
  1264.                   UINT             nRow1,
  1265.                   UINT             nRow2) {
  1266.                     
  1267.     UINT  wClusRows, 
  1268.           wClusNum1,
  1269.           wClusNum2,
  1270.           wClusPos1,
  1271.           wClusPos2;
  1272.     LPSTR lpStr1, 
  1273.           lpStr2,
  1274.           lpTemp;      
  1275.     HANDLE hTemp;      
  1276.     
  1277.     // line 1
  1278.     wClusRows = (ROW_CLUSTER_SIZE / (sizeof (LPSTR) *
  1279.         lpGrigliaStruct->wCols));
  1280.     wClusNum1 = nRow1 / wClusRows;        
  1281.     wClusPos1 = (nRow1 -  wClusNum1 * wClusRows)  *        
  1282.                  lpGrigliaStruct->wCols;                   
  1283.     lpStr1    = (LPSTR)((LPLONG)lpGrigliaStruct->cRowCluster 
  1284.                         [wClusNum1].lpCluster + wClusPos1);    
  1285.  
  1286.     // line2
  1287.     wClusNum2 = nRow2 / wClusRows;        
  1288.     wClusPos2 = (nRow2 - wClusNum2 * wClusRows) *        
  1289.                  lpGrigliaStruct->wCols;                  
  1290.     lpStr2    = (LPSTR)((LPLONG)lpGrigliaStruct->cRowCluster 
  1291.                         [wClusNum2].lpCluster + wClusPos2);    
  1292.  
  1293.     if (hTemp = GlobalAlloc (GHND,        
  1294.                              sizeof (LPSTR) * lpGrigliaStruct->wCols)) {
  1295.         lpTemp = (LPSTR)GlobalLock (hTemp);
  1296.         
  1297.         _fmemcpy (lpTemp,
  1298.                   lpStr1,
  1299.                   (sizeof (LPSTR) * lpGrigliaStruct->wCols));  
  1300.         _fmemcpy (lpStr1,
  1301.                   lpStr2,
  1302.                   (sizeof (LPSTR) * lpGrigliaStruct->wCols));  
  1303.         _fmemcpy (lpStr2,
  1304.                   lpTemp,
  1305.                   (sizeof (LPSTR) * lpGrigliaStruct->wCols));  
  1306.         
  1307.         GlobalUnlock (hTemp);                
  1308.         GlobalFree   (hTemp);    
  1309.     }           
  1310. }
  1311.  
  1312. //---------------------------------------------------------------------------
  1313. // SortText
  1314. //---------------------------------------------------------------------------
  1315. void SortText (PGRIGLIA         lpGrigliaStruct,
  1316.                LPFINDTEXT     lpFind) {
  1317.  
  1318.     SHORT nLines, nGap, i, j;            
  1319.  
  1320.     nLines = lpGrigliaStruct->wRows - 1 - lpGrigliaStruct->wFixedRows;
  1321.  
  1322.     for (nGap = nLines / 2; nGap > 0; nGap /= 2) {
  1323.         for (i = nGap; i < nLines; i++) {
  1324.             for (j = i - nGap;
  1325.                  j >= 0 &&
  1326.                  (CompareLines (lpGrigliaStruct, 
  1327.                                 lpFind, 
  1328.                                 j + lpGrigliaStruct->wFixedRows, 
  1329.                                 j + lpGrigliaStruct->wFixedRows + nGap) > 0);
  1330.                  j -= nGap) 
  1331.                 SwitchLines (lpGrigliaStruct,
  1332.                              j + lpGrigliaStruct->wFixedRows, 
  1333.                              j + lpGrigliaStruct->wFixedRows + nGap);
  1334.         }
  1335.     }
  1336. }
  1337.